﻿using FEM.Result;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PBSD_Development
{
    /// <summary>
    /// 单元组
    /// </summary>
    public class ElementGroupObj
    {
        /// <summary>
        /// 单元组
        /// </summary>
        private ElementGroup elementGroup { set; get; }

        /// <summary>
        /// 弹塑性分析结果
        /// </summary>
        private FEMResult result { set; get; }

        /// <summary>
        /// 限值信息
        /// </summary>
        private LimitSet limits
        {
            get
            {
                return this.result.Limits;
            }
        }

        /// <summary>
        /// 单元列表
        /// </summary>
        private List<ElementObj> elementList { set; get; }

        /// <summary>
        /// 单元组名称
        /// </summary>
        public string Descp
        {
            get
            {
                return this.elementGroup.Descp;
            }
        }

        /// <summary>
        /// 单元组类型
        /// </summary>
        public GroupType GroupTypeEnum
        {
            get
            {
                return this.elementGroup.Type;
            }
        }

        /// <summary>
        /// 特定楼层的构件性能状态占比
        /// </summary>
        /// <param name="loadcase"></param>
        /// <param name="storey"></param>
        /// <returns></returns>
        public List<double> GetStoreyDeformPerformRatio(LoadCaseObj loadcase, StoreyObj storey)
        {
            //获得所有楼层性能状态
            var performDict = this.GetStoreyDeformPerformRatio(loadcase, storey.Tower);
            //获得对应楼层的性能状态占比
            if (performDict.ContainsKey(storey.StoreyIndex)) return performDict[storey.StoreyIndex];
            else return new List<double> { 0, 0, 0, 0, 0, 0, 0 };
        }

        /// <summary>
        /// 单元组各楼层构件性能状态占比
        /// </summary>
        /// <param name="loadcase"> 工况 </param>
        /// <param name="tower"> 塔楼 </param>
        /// <returns> 各楼层构件性能状态占比 </returns>
        public Dictionary<int, List<double>> GetStoreyDeformPerformRatio(LoadCaseObj loadcase, TowerObj tower)
        {
            //获得塔楼
            var femTower = this.result.Towers[tower.TowerIndex];
            //构造参数
            var performParam = new PerformRatioParam(this.limits, femTower, ElementPerformType.Default, SecResultType.DeformPerform);
            //获得楼层性能占比
            return this.elementGroup.GetStoreyPerformRatio(loadcase.Name, performParam);
        }

        /// <summary>
        /// 获得所有单元
        /// </summary>
        /// <returns> 单元对象列表 </returns>
        public List<ElementObj> GetElementList()
        {
            return this.elementList;
        }

        /// <summary>
        /// 楼层内单元组的所有单元
        /// </summary>
        /// <param name="storey"> 楼层对象 </param>
        /// <returns> 单元对象列表 </returns>
        public List<ElementObj> GetElementList(StoreyObj storey)
        {
            return (from element in this.elementList
                    where storey.isSameStorey(element.TowerIndex, element.StoreyIndex)
                    select element).ToList();
        }

        /// <summary>
        /// 楼层内单元组构件的平均转角
        /// </summary>
        /// <param name="loadcase"> 工况 </param>
        /// <param name="storey"> 楼层 </param>
        /// <returns> 平均转角 </returns>
        public float GetAVGDeform(LoadCaseObj loadcase, StoreyObj storey)
        {
            return (from element in this.GetElementList(storey) 
                    select element.GetDeform(loadcase)).ToList().Average();
        }

        /// <summary>
        /// 楼层内单元组构件的平均能力需求比
        /// </summary>
        /// <param name="loadcase"> 工况 </param>
        /// <param name="storey"> 楼层 </param>
        /// <param name="deformType"> 性能类型 </param>
        /// <returns> 需求能力比 </returns>
        public float GetAVGDeformDCR(LoadCaseObj loadcase, StoreyObj storey, DeformType deformType)
        {
            return (from element in this.GetElementList(storey)
                    select element.GetDeformDCR(loadcase, deformType)).ToList().Average();
        }

        /// <summary>
        /// 楼层内单元组构件的最大需求能力比
        /// </summary>
        /// <param name="loadcase"> 工况 </param>
        /// <param name="storey"> 楼层 </param>
        /// <param name="deformType"> 性能类型 </param>
        /// <returns> 需求能力比 </returns>
        public float GetMaxDeformDCR(LoadCaseObj loadcase, StoreyObj storey, DeformType deformType)
        {
            return (from element in this.GetElementList(storey)
                    select element.GetDeformDCR(loadcase, deformType)).ToList().Max();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public ElementGroupObj()
        {
            this.elementList = new List<ElementObj>();
        }

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="group"></param>
        public ElementGroupObj(ElementGroup group, FEMResult result): this()
        {
            //初始化
            this.elementGroup = group;
            this.result = result;
            //获得单元
            foreach(var element in this.elementGroup.Elements)
            {
                this.elementList.Add(new ElementObj(element, result));
            }
        }
    }
}
